#ifndef SEVENCARDSTUDGAME_H
#define SEVENCARDSTUDGAME_H

#include "VPGameBase.h"
#include "shue.h"
#include "jokcrdmg.h"

#include "VPHand.h"
#include "fivecardhand.h"

class VPConnection;
class VPGuts;
class SevenCardSavedGame;
class SevenCardStudSQL;

class SevenCardStudGame : public VPGameBase
{
public:

    SevenCardStudGame(VPConnection* pConn, GameDBInterface *pDBInterface);

    SevenCardStudGame(VPConnection* pConn, GameDBInterface *pDBInterface, SevenCardSavedGame *pSave);

    ~SevenCardStudGame();


    //  ************ overrides of VPGameBase methods ************

    // Processes game specific messages from the client
    virtual bool8 handleMessage(unsigned char *pucMsgBuf, int32 nMsgLen);

    // Is game state valid?
    virtual bool8 initOk();

    // Called when restoring a saved game.  Sends game state data to the client.
    virtual void send();
    
    // What paytable are we using for the main game bet payouts?
    virtual int32 getPayFreq()              { return m_ucPayTable;          }

    virtual bool8 getDoubleUpEnabled()      { return m_bDblUpEnabled;       }    

    // side bet info
    virtual uint8 getSideBetPayTable()      { return m_ucSideBetPayTable;   }
    virtual bool8 getSideBetEnabled()       { return m_bSideBetEnabled;     }

protected:

    // called to handle the initial 'D' deal message from the client.  Starts a new game.
    int32 deal(int32 nBet, int32 nSideBetBet, uint8 ucSideBetCard);

    // called when the user has made a second or third bet and hit the "Deal" button
    void showNext(int32 nBet);

    // called when the user has made the fourth bet, OR has hit the "Deal All" button with or without a bet.
    void showAll(int32 nBet);

    // The user has agreed to play double or nothing...send them the visible cards
    bool8 doubleUpDeal();

    // The user has DECLINED to play double or nothing.  They get to keep their money.  End the game.
    bool8 doubleUpDeny();

    // the user played double or nothing and has selected "big" or "small".  Process their selection.
    int32 doubleUpSelect(uint8 ucBigSmall);

    // puts some game state info in the save object.
    void  save(SevenCardSavedGame* saved);

    // the game is over, figure out what the player won, if anything.
    void  calcPayout();

    // finds the best 5 card hand out of the 7 cards.
    int32 findBestHand(VPHand& startingHand, FiveCardHand& bestHand, uint8 aucBestCards[]);

    // finds the best 5 card hand out of the 7 cards, NOT COUNTING JOKERS.
    int32 findBestNoJokerHand(VPHand& noJokerHand, FiveCardHand& bestHand);

    // looks at a 5 card hand and figures out the rank of the hand, and if it's better than the current best hand.
    void  evaluateRank(VPHand &testHand, int32& nBestRank, FiveCardHand &bestHand, uint8 aucBestCards[]);



    
    VPConnection    *m_pConn;           // connection to the client

    SevenCardStudSQL *m_pDBInterface;   // connection to the database

    GameStates      m_eState;           // current game state
    int32           m_nPhase;           // what bet is the user on?

    // note that these two must come before any of the "hand" objects that use them, for constructor order purposes.
    JokerCardMgr    m_jokerCardMgr;     // card manager for the deck that can contain jokers.
    CardMgr         m_stdCardMgr;       // card manager used for double up and non-joker containing hands.

	ShueGameInfo	m_sgi;				// used to pass info to the shue instances

    FiveCardHand    m_bestHand;         // best 5 card hand out that can be made from the 7 dealt cards with jokers replaced by the card they're substituting for.
    int32           m_nBestHandRank;    // rank of best hand
    uint8           m_aucBestCards[5];  // the best 5 card hand, with jokers as actual jokers, not as the card they're substituting for in the hand.

    VPHand          m_hand;             // the 7 dealt cards

    uint8           m_ucPayTable;       // currently active pay table
    int32           m_nPayout;          // amt the player won on the main game (not including sidebet payout)

    int32           m_nBalance;         // player's last known balance

    int32           m_nBet;             // player's 1st bet
    int32           m_nBet_2;           // player's 2nd bet
    int32           m_nBet_3;           // player's 3rd bet
    int32           m_nBet_4;           // player's 4th bet
    int32           m_nTotalBet;        // sum of all of players bets (not including sidebet).

    bool8           m_bDblUpEnabled;    // is double up turned on?
    uint8           m_ucDblUpCard;      // the big/small card that they player has to guess
    int32           m_nDblUpRank;       // the rank of the big/small card.
    int32           m_nDblUpRound;      // how many rounds of double up has the user player played so far?
    int32           m_nDblUpPayout;     // the current win amt for the player on double up
    int32           m_nDblUpPayType;    // did player win or lose the last double up round?
    int32           m_nDblUpWon;        // how many double up rounds has the player won 
    VPHand          m_dblUpHand;        // the cards the user was dealt on the current double up round
    
	int32			m_nDlbUpCapAmount;	// what is the maximum amount we will allow and keep offering double ups

    bool8           m_bSideBetEnabled;  // are sidebets enabled?
    uint8           m_ucSideBetRank;    // what rank has the player selected for their side bet
    int32           m_nSideBet;         // amount of the user's side bet
    int32           m_nSideBetPayout;   // how much did the user win on their side bet
    uint8           m_ucSideBetPayTable;// what paytable are we using for side bet payouts?
    int32           m_nSideBetWinType;  // What was the rank of the hand that the player won the side bet on

    uint8           m_ucDeckConfiguration;  // controls the number of cards in the deck.  0=52, 1=53, 2=54.

    static const int32 m_anPayTable[9][11];         // pay tables used for payouts on the main game
    static const int32 m_anSideBetPayTable[9][11];  // pay tables used for payouts on sidebets
    static const int32 m_anDeckSize[3];             // number of cards for the 3 supported deck configurations

};




#endif